﻿using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;

namespace PickGold.Api
{
	public static class SetupApi
	{
		public const string DLL = Common.DLL_SETUPAPI;

		//为设备的详细信息分配一个内存块函数
		[DllImport(DLL, SetLastError = true)]
		public static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, [MarshalAs(UnmanagedType.LPStr)] string enumerator, IntPtr hParent, uint flags);
		[DllImport(DLL, SetLastError = true)]
		public static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, [MarshalAs(UnmanagedType.LPStr)] string enumerator, IntPtr hParent, DIGCF flags);
		//释放上一个函数分配的内存函数 
		[DllImport(DLL, SetLastError = true)]
		public static extern int SetupDiDestroyDeviceInfoList(IntPtr lpInfoSet);
		//从设备信息中获取设备的接口数据 
		[DllImport(DLL, SetLastError = true)]
		public static extern bool SetupDiEnumDeviceInterfaces(IntPtr lpDeviceInfoSet, uint nDeviceInfoData, ref Guid gClass, uint nIndex, ref DeviceInterfaceData oInterfaceData);
		/// <summary>
		/// 从设备接口数据中获取接口的详细信息的函数
		/// 必须调用两次 第1次返回长度 第2次获取数据
		/// </summary>
		/// <param name="deviceInfoSet"></param>
		/// <param name="deviceInterfaceData"></param>
		/// <param name="deviceInterfaceDetailData"></param>
		/// <param name="deviceInterfaceDetailDataSize"></param>
		/// <param name="requiredSize"></param>
		/// <param name="deviceInfoData"></param>
		/// <returns></returns>
		[DllImport(DLL, SetLastError = true)]
		public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref DeviceInterfaceData deviceInterfaceData, IntPtr deviceInterfaceDetailData, uint deviceInterfaceDetailDataSize, ref uint requiredSize, IntPtr deviceInfoData);
		[DllImport(DLL, SetLastError = true, CharSet = CharSet.Auto)]
		public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref DeviceInterfaceData deviceInterfaceData, IntPtr deviceInterfaceDetailData, uint deviceInterfaceDetailDataSize, ref uint requiredSize, ref DeviceInfoData deviceInfoData);
		[DllImport(DLL, SetLastError = true, CharSet = CharSet.Auto)]
		public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref DeviceInterfaceData deviceInterfaceData, ref DeviceInterfaceDetailData deviceInterfaceDetailData, uint deviceInterfaceDetailDataSize, ref uint requiredSize, ref DeviceInfoData deviceInfoData);
	}

	[StructLayout(LayoutKind.Sequential)]
	public struct DeviceInterfaceData
	{
		public int cbSize;
		public Guid interfaceClassGuid;
		public int flags;
		public int reserved;
	}

	[StructLayout(LayoutKind.Sequential)]
	//public class DeviceInfoData
	public struct DeviceInfoData
	{
		public DeviceInfoData(object @null)
		{
			cbSize = Marshal.SizeOf(typeof(DeviceInfoData));
			classGuid = Guid.Empty;//temp  
			devInst = 0;//dumy
			reserved = 0;
		}

		public int cbSize;
		public Guid classGuid;
		public int devInst;
		public int reserved;
	}

	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public struct DeviceInterfaceDetailData
	{
		public int cbSize;
		public short devicePath;
	}

	public enum DIGCF
	{
		DEFAULT = 0x1,
		PRESENT = 0x2,
		ALLCLASSES = 0x4,
		PROFILE = 0x8,
		DEVICEINTERFACE = 0x10
	}
}
